package com.allm.ai.common.properties;

import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.validation.annotation.Validated;

import jakarta.validation.Valid;
import jakarta.validation.constraints.NotBlank;
import jakarta.validation.constraints.NotNull;
import jakarta.validation.constraints.Pattern;
import jakarta.validation.constraints.Positive;

/**
 * EnPlatform Assistant 统一配置属性
 * 整合所有模块的配置，避免配置冲突
 *
 * @author com.enplatform.assistant
 * @since 1.0.0
 */
@Data
@Validated
@ConfigurationProperties(prefix = "allm.ai.common")
public class AllmAiCommonProperties {

    @Valid
    @NotNull
    private Application application = new Application();

    @Valid
    @NotNull
    private Ai ai = new Ai();

    @Valid
    @NotNull
    private Vectorstore vectorstore = new Vectorstore();

    @Valid
    @NotNull
    private Milvus milvus = new Milvus();

    @Valid
    @NotNull
    private Embeddings embeddings = new Embeddings();

    @Valid
    @NotNull
    private Excel excel = new Excel();

    @Valid
    @NotNull
    private Model model = new Model();

    @Valid
    @NotNull
    private Knowledge knowledge = new Knowledge();

    /**
     * 应用基本配置
     * 整合原ApplicationProperties的内容
     */
    @Data
    public static class Application {
        /**
         * 应用名称
         */
        @NotBlank
        private String name = "EnPlatform Assistant";

        /**
         * 应用版本
         */
        @NotBlank
        private String version = "1.0.0";

        /**
         * 应用描述
         */
        @NotBlank
        private String description = "TableGPT Excel Analyzer with Knowledge Base Integration";

        /**
         * 开发模式
         */
        private boolean devMode = false;

        @Valid
        @NotNull
        private File file = new File();

        @Valid
        @NotNull
        private Cache cache = new Cache();

        /**
         * 文件处理配置
         */
        @Data
        public static class File {
            /**
             * 文件上传路径
             */
            @NotBlank
            private String uploadPath = "./uploads";

            /**
             * 临时文件路径
             */
            @NotBlank
            private String tempPath = "./temp";

            /**
             * 最大文件大小(MB)
             */
            @Positive
            private long maxSize = 100;

            /**
             * 允许的文件类型
             */
            @NotNull
            private String[] allowedTypes = {"xlsx", "xls", "csv", "pdf", "txt"};
        }

        /**
         * 缓存配置
         */
        @Data
        public static class Cache {
            /**
             * 缓存类型
             */
            @NotBlank
            @Pattern(regexp = "memory|redis|caffeine")
            private String type = "memory";

            /**
             * 缓存过期时间(秒)
             */
            @Positive
            private long ttl = 3600;

            /**
             * 最大缓存条目数
             */
            @Positive
            private int maxEntries = 1000;
        }
    }

    /**
     * AI 配置
     */
    @Data
    public static class Ai {
        @NotBlank
        @Pattern(regexp = "mock|real|smart|local|gitee")
        private String provider = "local";

        @Valid
        @NotNull
        private OpenAi openai = new OpenAi();

        @Valid
        @NotNull
        private Local local = new Local();

        @Valid
        @NotNull
        private Gitee gitee = new Gitee();

        @Data
        public static class OpenAi {
            private String apiKey;

            @NotBlank
            private String baseUrl = "https://api.openai.com";

            @NotBlank
            private String model = "text-embedding-ada-002";

            @Positive
            private Integer timeout = 30000;
        }

        @Data
        public static class Local {
            @NotBlank
            private String baseUrl = "http://localhost:8081";

            @NotBlank
            private String model = "all-minilm:l6-v2";

            @Positive
            private Integer timeout = 30000;
        }

        @Data
        public static class Gitee {
            private String apiKey;

            @NotBlank
            private String baseUrl = "https://ai.gitee.com/v1";

            @NotBlank
            private String model = "Qwen3-Embedding-4B";

            @Positive
            private Integer timeout = 30000;

            private Boolean enabled = true;
        }
    }

    /**
     * 向量存储配置
     */
    @Data
    public static class Vectorstore {
        @NotBlank
        @Pattern(regexp = "mock|milvus|elasticsearch|redis")
        private String provider = "milvus";

        @NotNull
        private Boolean enabled = true;
    }

    /**
     * Milvus 配置
     * 整合原ApplicationProperties中的Milvus配置
     */
    @Data
    public static class Milvus {
        @NotBlank
        private String host = "localhost";

        @Positive
        private Integer port = 19530;

        @NotBlank
        private String database = "default";

        /**
         * 用户名（可选，用于认证）
         */
        private String username = "";

        /**
         * 密码（可选，用于认证）
         */
        private String password = "";

        /**
         * 是否启用TLS
         */
        private boolean enableTls = false;

        @NotBlank
        private String collectionName = "knowledge_base";

        @Positive
        private Integer dimension = 384;

        @Positive
        private Integer shardsNum = 2;

        @NotBlank
        private String indexType = "IVF_FLAT";

        @NotBlank
        private String metricType = "COSINE";

        @NotBlank
        private String indexParams = "{\"nlist\":1024}";

        @NotBlank
        private String searchParams = "{\"nprobe\":10}";

        @Valid
        @NotNull
        private Connection connection = new Connection();

        @Valid
        @NotNull
        private Collection collection = new Collection();

        @Valid
        @NotNull
        private Index index = new Index();

        /**
         * 连接配置
         */
        @Data
        public static class Connection {
            /**
             * 连接超时时间(毫秒)
             */
            @Positive
            private long timeout = 10000L;

            /**
             * 保持连接时间(毫秒)
             */
            @Positive
            private long keepAlive = 30000L;

            /**
             * 最大重试次数
             */
            @Positive
            private int maxRetries = 3;

            /**
             * 重试间隔(毫秒)
             */
            @Positive
            private long retryInterval = 1000L;

            /**
             * 连接池大小
             */
            @Positive
            private int poolSize = 10;
        }

        /**
         * 集合配置
         */
        @Data
        public static class Collection {
            /**
             * 默认集合名称前缀
             */
            @NotBlank
            private String namePrefix = "enplatform_";

            /**
             * 默认分片数量
             */
            @Positive
            private int shardNum = 2;

            /**
             * 默认副本数量
             */
            @Positive
            private int replicaNum = 1;

            /**
             * 自动创建集合
             */
            private boolean autoCreate = true;

            /**
             * 自动创建索引
             */
            private boolean autoIndex = true;
        }

        /**
         * 索引配置
         */
        @Data
        public static class Index {
            /**
             * 默认索引类型
             */
            @NotBlank
            private String type = "IVF_FLAT";

            /**
             * 默认相似性度量
             */
            @NotBlank
            private String metric = "COSINE";

            /**
             * 索引参数
             */
            @NotBlank
            private String params = "{\"nlist\": 1024}";

            /**
             * 搜索参数
             */
            @NotBlank
            private String searchParams = "{\"nprobe\": 10}";
        }
    }

    /**
     * 嵌入配置
     */
    @Data
    public static class Embeddings {
        @Valid
        @NotNull
        private Primary primary = new Primary();

        @Data
        public static class Primary {
            @NotBlank
            private String baseUrl = "http://localhost:8081";

            @NotBlank
            private String modelName = "all-minilm:l6-v2";

            @Positive
            private Integer dimension = 384;

            @Positive
            private Integer timeout = 30000;

            @Positive
            private Integer batchSize = 100;
        }
    }

    /**
     * Excel 处理配置
     */
    @Data
    public static class Excel {
        /**
         * 最大文件大小(字节) - 10MB
         */
        @Positive
        private Integer maxFileSize = 10485760;

        /**
         * 最大行数
         */
        @Positive
        private Integer maxRows = 10000;

        /**
         * 批处理大小
         */
        @Positive
        private Integer batchSize = 1000;

        /**
         * 是否启用缓存
         */
        @NotNull
        private Boolean enableCache = true;

        /**
         * 临时目录
         */
        @NotBlank
        private String tempDir = "/tmp/enplatform-assistant";

        /**
         * 支持的文件格式
         */
        @NotNull
        private String[] supportedFormats = {"xlsx", "xls", "csv"};
    }

    /**
     * 模型服务配置
     */
    @Data
    public static class Model {
        @NotBlank
        @Pattern(regexp = "default|local|openai|azure")
        private String provider = "default";

        @Valid
        @NotNull
        private OpenAi openai = new OpenAi();

        @Valid
        @NotNull
        private Local local = new Local();

        @Valid
        @NotNull
        private Azure azure = new Azure();

        @Data
        public static class OpenAi {
            private String apiKey;

            @NotBlank
            private String baseUrl = "https://api.openai.com";

            @NotBlank
            private String textModel = "gpt-3.5-turbo";

            @NotBlank
            private String embeddingModel = "text-embedding-ada-002";

            @NotBlank
            private String chatModel = "gpt-3.5-turbo";

            @Positive
            private Integer timeout = 30000;

            @Positive
            private Integer maxTokens = 2048;

            private Double temperature = 0.7;
        }

        @Data
        public static class Local {
            @NotBlank
            private String baseUrl = "http://localhost:11434";

            @NotBlank
            private String textModel = "qwen2:0.5b";

            @NotBlank
            private String embeddingModel = "all-minilm:l6-v2";

            @NotBlank
            private String chatModel = "qwen2:0.5b";

            @Positive
            private Integer timeout = 30000;

            @Positive
            private Integer maxTokens = 2048;

            private Double temperature = 0.7;
        }

        @Data
        public static class Azure {
            private String apiKey;

            @NotBlank
            private String endpoint = "https://your-resource.openai.azure.com";

            @NotBlank
            private String deploymentName = "gpt-35-turbo";

            @NotBlank
            private String apiVersion = "2023-05-15";

            @Positive
            private Integer timeout = 30000;

            @Positive
            private Integer maxTokens = 2048;

            private Double temperature = 0.7;
        }
    }

    /**
     * 知识库服务配置
     */
    @Data
    public static class Knowledge {
        @NotBlank
        @Pattern(regexp = "default|simple|advanced-rag")
        private String provider = "default";

        @Valid
        @NotNull
        private Search search = new Search();

        @Valid
        @NotNull
        private Cache cache = new Cache();

        @Valid
        @NotNull
        private Rag rag = new Rag();

        @Data
        public static class Search {
            /**
             * 默认搜索结果数量
             */
            @Positive
            private Integer defaultTopK = 10;

            /**
             * 默认相似度阈值
             */
            private Double defaultThreshold = 0.3;

            /**
             * 最大搜索结果数量
             */
            @Positive
            private Integer maxTopK = 100;

            /**
             * 搜索超时时间(毫秒)
             */
            @Positive
            private Integer timeout = 5000;
        }

        @Data
        public static class Cache {
            /**
             * 是否启用缓存
             */
            @NotNull
            private Boolean enabled = true;

            /**
             * 缓存过期时间(秒)
             */
            @Positive
            private Long ttl = 3600L;

            /**
             * 最大缓存条目数
             */
            @Positive
            private Integer maxEntries = 10000;

            /**
             * 缓存类型
             */
            @NotBlank
            @Pattern(regexp = "memory|redis|caffeine")
            private String type = "memory";
        }

        @Data
        public static class Rag {
            /**
             * 是否启用RAG功能
             */
            @NotNull
            private Boolean enabled = true;

            /**
             * 上下文窗口大小
             */
            @Positive
            private Integer contextWindow = 4096;

            /**
             * 检索文档数量
             */
            @Positive
            private Integer retrievalTopK = 5;

            /**
             * 检索阈值
             */
            private Double retrievalThreshold = 0.5;

            /**
             * 是否启用重排序
             */
            @NotNull
            private Boolean enableReranking = true;

            /**
             * 是否启用查询扩展
             */
            @NotNull
            private Boolean enableQueryExpansion = false;
        }
    }
}
